package com.llmm.utils;

import java.io.*;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * @description: 文件工具类。含文件删除，读取，新建。
 * @author: llmm
 * @date: 2022/5/6
 */
public class FileLlmmUtils {

    /**
     * @description: 文件夹内删除。
     * @param: filePath 文件路径地址。
     * @return: void
     * @author: llmm
     * @date: 2022/5/7
     */
    public static void deleteFile(File file) {
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
            } else if (file.isDirectory()) {
                File files[] = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    deleteFile(files[i]);
                }
                file.delete();
            }
        } else {
            System.out.println("所删除的文件不存在！" + '\n');
        }
    }


    /**
     * @description: 文本文件读取内容
     * @param: filePath  xx\xx\aaa.txt
     * @return: java.lang.String  文件内容。
     * @author: llmm
     * @date: 2022/5/7
     */
    public static String readJsonData(String filePath) {
        StringBuffer strbuffer = new StringBuffer();
        File myFile = new File(filePath);
        if (!myFile.exists()) {
            System.err.println("Can't Find " + filePath);
        }
        try {
            FileInputStream fis = new FileInputStream(filePath);
            InputStreamReader inputStreamReader = new InputStreamReader(fis, "UTF-8");
            BufferedReader in = new BufferedReader(inputStreamReader);
            String str;
            while ((str = in.readLine()) != null) {
                strbuffer.append(str);
            }
            in.close();
        } catch (IOException e) {
            e.getStackTrace();
        }
        return strbuffer.toString();

    }


    /**
     * @description: 文本文件修改（新增）。
     * @param: filePath 文件路径 xx\xx\aa.txt
     * @param: content 文件内容
     * @return: boolean
     * @author: llmm
     * @date: 2022/5/7
     */
    public static boolean writeFile(String filePath, String content) {
        FileWriter fw;
        try {
            fw = new FileWriter(filePath);
            PrintWriter out = new PrintWriter(fw);
            out.write(content);
            out.println();
            fw.close();
            out.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }


    /**
     * @description: zip文件解压
     * @param: filePath zip文件路径
     * @param: zipDir zip文件解压的路径
     * @return: java.lang.String
     * @author: llmm
     * @date: 2022/5/21
     */
    public static String unzip(String filePath, String zipDir) {
        String name = "";
        int BUFFER = 1024;
        try {
            BufferedOutputStream dest = null;
            BufferedInputStream is = null;
            ZipEntry entry;
            ZipFile zipfile = new ZipFile(filePath);

            Enumeration dir = zipfile.entries();
            while (dir.hasMoreElements()) {
                entry = (ZipEntry) dir.nextElement();

                if (entry.isDirectory()) {
                    name = entry.getName();
                    name = name.substring(0, name.length() - 1);
                    File fileObject = new File(zipDir + name);
                    fileObject.mkdir();
                }
            }

            Enumeration e = zipfile.entries();
            while (e.hasMoreElements()) {
                entry = (ZipEntry) e.nextElement();
                if (entry.isDirectory()) {
                    continue;
                } else {
                    is = new BufferedInputStream(zipfile.getInputStream(entry));
                    int count;
                    byte[] dataByte = new byte[BUFFER];
                    FileOutputStream fos = new FileOutputStream(zipDir + entry.getName());
                    dest = new BufferedOutputStream(fos, BUFFER);
                    while ((count = is.read(dataByte, 0, BUFFER)) != -1) {
                        dest.write(dataByte, 0, count);
                    }
                    dest.flush();
                    dest.close();
                    is.close();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return name;
    }


    /**
     * @description: 载多个文件或文件夹中的文件并打包zip。
     * @param: url 保存路径。xx/xx/aa.zip
     * @param: fileList 所有文件。
     * @param: keepDir 是否保持文件目录结构。
     * @return: void
     * @author: llmm
     * @date: 2022/5/21
     */
    public static void toZip(List<String> srcFiles, String url, boolean keepDir) throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(new FileOutputStream(url));
            for (String file : srcFiles) {
                File srcFile = new File(file);
                compress(srcFile, zos, srcFile.getName(), keepDir);
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) + " ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            if (zos != null) {
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * 递归压缩方法
     * @param sourceFile 源文件
     * @param zos        zip输出流
     * @param name       压缩后的名称
     * @param keepDir    是否保留原来的目录结构,true:保留目录结构;
     *                   false:所有文件跑到压缩包根目录下(注意：不保留目录结构可能会出现同名文件,会压缩失败)
     * @throws Exception
     */
    private static void compress(File sourceFile, ZipOutputStream zos, String name,
                                 boolean keepDir) throws Exception {
        byte[] buf = new byte[1024];
        if (sourceFile.isFile()) {
            // 向zip输出流中添加一个zip实体，构造器中name为zip实体的文件的名字
            zos.putNextEntry(new ZipEntry(name));
            // copy文件到zip输出流中
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            // Complete the entry
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                // 需要保留原来的文件结构时,需要对空文件夹进行处理
                if (keepDir) {
                    // 空文件夹的处理
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    // 没有文件，不需要文件的copy
                    zos.closeEntry();
                }
            } else {
                for (File file : listFiles) {
                    // 判断是否需要保留原来的文件结构
                    if (keepDir) {
                        // 注意：file.getName()前面需要带上父文件夹的名字加一斜杠,
                        // 不然最后压缩包中就不能保留原来的文件结构,即：所有文件都跑到压缩包根目录下了
                        compress(file, zos, name + "/" + file.getName(), keepDir);
                    } else {
                        compress(file, zos, file.getName(), keepDir);
                    }

                }
            }
        }
    }


    /**
     * @description: 获取文件夹下的某个类型的所有文件。
     * @param: dir 文件夹
     * @param: suffix 文件格式 .java 。获取所有文件设置为空字符串即可。
     * @param: list 存放文件
     * @return: java.util.List
     * @author: llmm
     * @date: 2022/5/22
     */
    public static List getFiles(File dir, String suffix, List list){

        File[] files = dir.listFiles();
        if (files !=null){
            for (File file : files) {
                if (file.isDirectory()){
                    getFiles(file,suffix,list);
                }else if (file.getName().endsWith(suffix)){
                    list.add(file);
                }
            }
        }
        return list;
    }


    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\Administrator\\Desktop\\新建文件夹");
        ArrayList<File> files = new ArrayList<>();
        List files1 = getFiles(file, ".md", files);
        for (Object o : files1) {
            System.out.println(o);
        }
    }

    public String aa(String aa){
        return "asfsjklas";
    }

    public String aa(){
        String aa="dada";
        return "asfsjkl";
    }

}
